using System.Collections.Generic;
using System;
namespace Mono.Boost.Graph
{
    public class StaticPropertyMap<T> : IDictionary<uint, T>
    {
        Pair<bool,T>[] _tab;
        int _count = 0;
        public StaticPropertyMap(uint n)
        {
            _tab = new Pair<bool, T>[n];
        }

        #region IEnumerable<T> Members

        public System.Collections.Generic.IEnumerator<T> GetEnumerator()
        {
            foreach (Pair<bool, T> t in _tab)
                if (t.first) yield return t.second;
        }

        #endregion

        #region IEnumerable Members

        System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
        {
            foreach (Pair<bool, T> t in _tab)
                if (t.first) yield return (object) t.second;
        }

        #endregion


        #region IDictionary<uint,T> Members

        public void Add(uint key, T value)
        {
            if (_tab[key].first) throw new ArgumentException("An element with the same key already exists in the PropertyMap");
            _tab[key].first = true;
            _tab[key].second = value;
            _count++;
        }

        public bool ContainsKey(uint key)
        {
            if (_tab.Length > key)
                return _tab[key].first;
            return false;
        }

        public ICollection<uint> Keys
        {
            get { throw new System.Exception("The method or operation is not implemented."); }
        }

        public bool Remove(uint key)
        {
            if (_tab[key].first) 
            {
                _count--;
                _tab[key].first = false;
                return true;
            }
            return false;
        }

        public bool TryGetValue(uint key, out T value)
        {
            value = _tab[key].second;
            return _tab[key].first;
        }

        public ICollection<T> Values
        {
            get { throw new System.Exception("The method or operation is not implemented."); }
        }

        public T this[uint key]
        {
            get
            {
                if (_tab[key].first)
                    return _tab[key].second;
                throw new ArgumentNullException("Key is null");
            }
            set
            {
                Remove(key);
                Add(key, value);
            }
        }

        #endregion

        #region ICollection<KeyValuePair<uint,T>> Members

        public void Add(KeyValuePair<uint, T> item)
        {
            Add(item.Key, item.Value);
        }

        public void Clear()
        {
            _tab = new Pair<bool, T>[_tab.Length];
            _count = 0;
        }

        public bool Contains(KeyValuePair<uint, T> item)
        {
            if (!_tab[item.Key].first) 
                return false;
            if (_tab[item.Key].second.Equals(item.Value))
                return false;
            return true;
        }

        public void CopyTo(KeyValuePair<uint, T>[] array, int arrayIndex)
        {
            throw new System.Exception("The method or operation is not implemented.");
        }

        public int Count
        {
            get { return _count; }
        }

        public bool IsReadOnly
        {
            get { return false; }
        }

        public bool Remove(KeyValuePair<uint, T> item)
        {
            throw new System.Exception("The method or operation is not implemented.");
        }

        #endregion

        #region IEnumerable<KeyValuePair<uint,T>> Members

        IEnumerator<KeyValuePair<uint, T>> IEnumerable<KeyValuePair<uint, T>>.GetEnumerator()
        {
            throw new System.Exception("The method or operation is not implemented.");
        }

        #endregion
    }
}
